#ifndef NET_BUFFER_H_
#define NET_BUFFER_H_

#include "base/base.h"

namespace net {
class Buffer {
  public:
    Buffer();

    void Revert() {
      mem_ = (u_char*) &buffer_[0];
      r_pos_ = w_pos_ = mem_;
      end_ = r_pos_ + buffer_.size();
    }

    void Resize(size_t size, bool reinit = true);

    size_t Capacity() {
      CHECK_GT(end_, mem_);
      return end_ - mem_;
    }

    // Should not be called.
    size_t FreeSize() {
      return end_ - w_pos_;
    }

    size_t ReadableSize() {
      CHECK(w_pos_ >= r_pos_ && w_pos_ < end_);
      return w_pos_ - r_pos_;
    }

    size_t WriteableSize() {
      CHECK(w_pos_ <= end_);
      return end_ - w_pos_;
    }

    ssize_t ReadFd(int32 fd);

    u_char* Retrieve(size_t size);
    u_char* Peek() const {
      return r_pos_;
    }

    template<typename Type> void RetrieveType(Type* t) {
      CHECK_NOTNULL(t);
      memcpy(t, Retrieve(sizeof *t), sizeof(*t));
    }

    void Append(const u_char* buf, size_t size);
    void Append(const char*buf) {
      Append((const u_char*) buf, ::strlen(buf));
    }
    void Append(const std::string* str) {
      Append((const u_char*) str->c_str(), str->size());
    }

    template<typename Type> void Append(const Type* t) {
      Append(t, sizeof *t);
    }

  private:
    std::vector<char> buffer_;
    u_char* r_pos_;
    u_char* w_pos_;
    u_char* mem_;
    u_char* end_;

    DISALLOW_COPY_AND_ASSIGN(Buffer);
};

}
#endif
